From 759f87088e51b9b5e26e4e2ba274f9a1c44778b2 Mon Sep 17 00:00:00 2001 From: "maf46@burn.cl.cam.ac.uk" Date: Fri, 18 Feb 2005 14:10:50 +0000 Subject: [PATCH] bitkeeper revision 1.1205.1.4 (4215f76aKShpc2MoKv20Ho-I6PFwGg) Bug fixes for out-of-bounds bug in the rewrite of debugtrace_printk --- xen/drivers/char/console.c | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c index 9ddfa2e90a..b513520703 100644 --- a/xen/drivers/char/console.c +++ b/xen/drivers/char/console.c @@ -479,13 +479,20 @@ void console_force_lock(void) static unsigned char *debugtrace_buf; /* Debug-trace buffer */ static unsigned int debugtrace_prd; /* Producer index */ static unsigned int debugtrace_kilobytes = 128, debugtrace_bytes; +static spinlock_t debugtrace_lock = SPIN_LOCK_UNLOCKED; integer_param("debugtrace", debugtrace_kilobytes); -#define DEBUGTRACE_MASK(_p) ((_p) & (debugtrace_bytes-1)) void debugtrace_reset(void) { + unsigned long flags; + + spin_lock_irqsave(&debugtrace_lock, flags); + if ( debugtrace_bytes != 0 ) memset(debugtrace_buf, '\0', debugtrace_bytes); + debugtrace_prd = 0; + + spin_unlock_irqrestore(&debugtrace_lock, flags); } void debugtrace_dump(void) @@ -498,23 +505,25 @@ void debugtrace_dump(void) /* Watchdog can trigger if we print a really large buffer. */ watchdog_on = 0; + spin_lock(&debugtrace_lock); + /* Print oldest portion of the ring. */ - serial_puts(sercon_handle, - &debugtrace_buf[DEBUGTRACE_MASK(debugtrace_prd)]); + serial_puts(sercon_handle, &debugtrace_buf[debugtrace_prd]); /* Print youngest portion of the ring. */ - debugtrace_buf[DEBUGTRACE_MASK(debugtrace_prd)] = '\0'; - serial_puts(sercon_handle, - &debugtrace_buf[0]); + debugtrace_buf[debugtrace_prd] = '\0'; + serial_puts(sercon_handle, &debugtrace_buf[0]); - debugtrace_reset(); + memset(debugtrace_buf, '\0', debugtrace_bytes); + debugtrace_prd = 0; + + spin_unlock(&debugtrace_lock); watchdog_on = _watchdog_on; } void debugtrace_printk(const char *fmt, ...) { - static spinlock_t _lock = SPIN_LOCK_UNLOCKED; static char buf[1024]; va_list args; @@ -524,16 +533,22 @@ void debugtrace_printk(const char *fmt, ...) if ( debugtrace_bytes == 0 ) return; - spin_lock_irqsave(&_lock, flags); + spin_lock_irqsave(&debugtrace_lock, flags); va_start(args, fmt); (void)vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); for ( p = buf; *p != '\0'; p++ ) - debugtrace_buf[DEBUGTRACE_MASK(debugtrace_prd++)] = *p; + { + debugtrace_buf[debugtrace_prd++] = *p; + + /* always leave a null byte at the end of the buffer */ + if (debugtrace_prd == debugtrace_bytes-1) + debugtrace_prd = 0; + } - spin_unlock_irqrestore(&_lock, flags); + spin_unlock_irqrestore(&debugtrace_lock, flags); } static int __init debugtrace_init(void) -- 2.30.2